package com.pactera.asmp.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.dao.FileParseMapper;
import com.pactera.asmp.server.entity.dbc.Message;
import com.pactera.asmp.server.pojo.FileParse;
import com.pactera.asmp.server.pojo.User;
import com.pactera.asmp.server.utils.DbcParseUtil;
import com.pactera.asmp.server.utils.MinioUtils;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: tlsserver
 * @Package com.pactera.asmp.server.service
 * @ClassName: FileParseServiceImpl
 * @Description: FileParseServiceImpl
 * @Date 2020/06/28 17:03
 * @Author lvzhiqiang
 * @Version 1.0
 */
@Service
@Slf4j
public class FileParseServiceImpl implements IFileParseService {
    private final static String DBC_SUFFIX = ".dbc";
    @Resource
    private FileParseMapper fileParseMapper;

    @Autowired
    private DbcParseUtil dbcParseUtil;

    @Autowired
    private MinioUtils minioUtils;

//    @Autowired
//    private SeaweedFsClient seaweedFsClient;
//
//    @Autowired
//    private FileTemplate fileTemplate;

    @Override
    public FileParse uploadAndInsert(MultipartFile file, Integer projectId) {
        User currUser = (User) SecurityUtils.getSubject().getPrincipal();
        if (null == currUser) {
            throw new CustomException(ResultCode.PERMISSION_EXPIRE);
        }

        // 文件格式校验
        if (!file.getOriginalFilename().endsWith(DBC_SUFFIX)) {
            throw new CustomException(ResultCode.FILE_ACCEPT_NOT_SUPPORT);
        }

        // =====================================文件服务器替换代码 start=========================================
        // 上传文件到服务器
//        SeaweedFsClient.SeaweedFsResponse seaweedFsResponse = new SeaweedFsClient.SeaweedFsResponse();
//        try {
//            seaweedFsResponse = seaweedFsClient.saveFile(file);
//        } catch (IOException e) {
//            log.error("dbc file upload error: ", e);
//            throw new CustomException(ResultCode.UPLOAD_ERROR);
//        }
//        FileParse fileParse = new FileParse();
//        fileParse.setFileName(seaweedFsResponse.getFileName());
//        fileParse.setFileSize(file.getSize());
//        fileParse.setFileId(seaweedFsResponse.getFileId());
//        fileParse.setFilePath(seaweedFsResponse.getFilePath());
//        fileParse.setProjectId(projectId);
//        fileParse.setType(1);
//        fileParse.setUserId(currUser.getId());
//        fileParse.setCreateTime(LocalDateTime.now());
//        fileParseMapper.insert(fileParse);

        String fileName;
        try {
            fileName = minioUtils.uploadFile(file);
        } catch (Exception e) {
            log.error("dbc file upload error: ", e);
            throw new CustomException(ResultCode.UPLOAD_ERROR);
        }
        FileParse fileParse = new FileParse();
        fileParse.setFileName(file.getOriginalFilename());
        fileParse.setFileSize(file.getSize());
        fileParse.setFileId(minioUtils.getBucketName());
        fileParse.setFilePath(fileName);
        fileParse.setProjectId(projectId);
        fileParse.setType(1);
        fileParse.setUserId(currUser.getId());
        fileParse.setCreateTime(LocalDateTime.now());
        fileParseMapper.insert(fileParse);

        // =====================================文件服务器替换代码 end=========================================

        return fileParse;
    }

    @Override
    public List<FileParse> selectByProjectId(Integer projectId) {
        FileParse attachFile = new FileParse();
        attachFile.setProjectId(projectId);
        return fileParseMapper.selective(attachFile);
    }

    @Override
    //@Async("asyncServiceExecutor" )
    public void parseFileAndUpdate(InputStream is, Long cid) {
        // 解析后的值
        String result = "";
        InputStream inputStringStream = null;
        try {
            // =====================================文件服务器替换代码 start=========================================

//            result = JSON.toJSONString(dbcParseUtil.parse(is), SerializerFeature.WriteMapNullValue);
//            String filename = System.currentTimeMillis() + ".json";
//            inputStringStream = new ByteArrayInputStream(result.getBytes());
//            FileHandleStatus status = fileTemplate.saveFileByStream(filename, inputStringStream);
//            String parseFileId = status.getFileId();
//
//            FileParse fileParse = new FileParse();
//            fileParse.setCid(cid);
//            fileParse.setParseFileId(parseFileId);
//            fileParse.setParseFilePath(fileTemplate.getFileUrl(parseFileId));
//            fileParseMapper.updateByPrimaryKeySelective(fileParse);

            List<Message> parse = dbcParseUtil.parse(is);
            result = JSON.toJSONString(parse, SerializerFeature.WriteMapNullValue);
            String filename = "dbcParse_" + cid + ".json";
            inputStringStream = new ByteArrayInputStream(result.getBytes());
            String contentType = "application/json";
            String newFileName = minioUtils.uploadFile(inputStringStream, filename, contentType);

            FileParse fileParse = new FileParse();
            fileParse.setCid(cid);
            fileParse.setParseFileId(minioUtils.getBucketName());
            fileParse.setParseFilePath(newFileName);
            fileParse.setParseContent(result);
            fileParse.setMessages(parse);
            fileParseMapper.updateByPrimaryKeySelective(fileParse);

            // =====================================文件服务器替换代码 end=========================================

        } catch (Exception e) {
            log.error("dbcParseUtil.parse error: ", e.getMessage());
            throw new CustomException(ResultCode.FILE_PARSE_FAIL);
        } finally {
            IOUtils.closeQuietly(inputStringStream, is);
        }
    }

    @Override
    public FileParse findByPrimaryKey(Long cid) {
        FileParse fileParse = new FileParse();
        fileParse.setCid(cid);
        List<FileParse> fileParses = fileParseMapper.selective(fileParse);
        if (null == fileParses || fileParses.isEmpty()) {
            return fileParse;
        }
        return fileParses.get(0);
    }

    @Override
    public Object getDbcParse(Long cid) {
        Object obj = null;
        FileParse fileParse = this.findByPrimaryKey(cid);

        // =====================================文件服务器替换代码 start=========================================

//        if (StringUtils.isNotBlank(fileParse.getParseFileId())) {
//            InputStream is = null;
//            ByteArrayOutputStream result = null;
//            try {
//                is = fileTemplate.getFileStream(fileParse.getParseFileId()).getInputStream();
//                result = new ByteArrayOutputStream();
//                byte[] buffer = new byte[1024];
//                int length;
//                while ((length = is.read(buffer)) != -1) {
//                    result.write(buffer, 0, length);
//                }
//                String str = result.toString(StandardCharsets.UTF_8.name());
//                obj = JSON.parse(str);
//            } catch (Exception e) {
//                log.error("getDbcParse error: ", e);
//            } finally {
//                IOUtils.closeQuietly(result, is);
//            }
//        }

        if (StringUtils.isNotBlank(fileParse.getParseFilePath())) {
            try {
                byte[] buffer = minioUtils.getObjectByte(fileParse.getParseFilePath());
                String str = new String(buffer, StandardCharsets.UTF_8.name());
                obj = JSON.parse(str);
            } catch (Exception e) {
                log.error("getDbcParse error: ", e.getMessage());
            }
        }

        // =====================================文件服务器替换代码 end=========================================

        return obj;
    }

    @Override
    public int deleteByPrimaryKey(Long cid) {
        return fileParseMapper.deleteByPrimaryKey(cid);
    }

    @Override
    public int deleteByPrimaryKeys(List<Long> list) {
        return fileParseMapper.deleteByPrimaryKeys(list);
    }
}
